package com.leo.foodmaster.admin.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.leo.foodmaster.admin.system.entity.Organ;
import com.leo.foodmaster.admin.system.entity.Role;
import com.leo.foodmaster.admin.system.entity.SysUser;
import com.leo.foodmaster.admin.system.mapper.OrganMapper;
import com.leo.foodmaster.admin.system.service.IOrganService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leo.foodmaster.admin.system.service.IRoleService;
import com.leo.foodmaster.admin.system.service.IUserService;
import com.leo.foodmaster.commons.entity.Result;
import com.leo.foodmaster.commons.entity.TreeSelect;
import com.leo.foodmaster.commons.enums.OrganTypeEnum;
import com.leo.foodmaster.commons.util.WebUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 机构表 服务实现类
 * </p>
 *
 * @author Leo
 * @since 2021-06-23
 */
@Service
public class OrganServiceImpl extends ServiceImpl<OrganMapper, Organ> implements IOrganService {
    @Resource
    private IUserService userService;
    @Resource
    private IRoleService roleService;


    /**
     * 根据机构Id查询机构和下属机构树形结构
     * @param organId 机构Id
     * @return List<TreeSelect>
     */
    @Override
    public List<TreeSelect> treeSelect(Long organId) {
        Organ organ = baseMapper.selectById(organId);
        TreeSelect treeSelect = new TreeSelect();
        treeSelect.setId(organ.getId());
        treeSelect.setLabel(organ.getName());
        selectChildren(treeSelect);
        List<TreeSelect> treeSelects = new ArrayList<>();
        treeSelects.add(treeSelect);
        return treeSelects;
    }

    /**
     * 条件分页查询公司列表
     * @param page 分页条件
     * @param name 公司名称
     * @param status 公司状态
     * @param beginTime 开始时间
     * @param endTime 结束时间
     * @return IPage<Organ>
     */
    @Override
    public IPage<Organ> getOrganPageList(Page<Organ> page, String name, String status, String beginTime, String endTime) {
        String organType = WebUtils.getUser().getOrganType();
        LambdaQueryWrapper<Organ> qw = Wrappers.lambdaQuery(Organ.class)
                .like(StrUtil.isNotBlank(name), Organ::getName, name)
                .eq(StrUtil.isNotBlank(status), Organ::getStatus, status)
                .ge(StrUtil.isNotBlank(beginTime), Organ::getCreateTime, beginTime)
                .le(StrUtil.isNotBlank(endTime), Organ::getCreateTime, endTime);
        if (!OrganTypeEnum.PLATFORM.getCode().equals(organType)) {
            qw.eq(Organ::getOrganId, WebUtils.getUser().getOrganId());
        }
        Page<Organ> pageList = page(page, qw);
        List<Organ> records = pageList.getRecords();
        for (Organ organ : records) {
            String foodSupplyTypes = organ.getFoodSupplyTypes();
            if (StrUtil.isNotBlank(foodSupplyTypes)) {
                String[] split = foodSupplyTypes.split(StrUtil.COMMA);
                organ.setFoodSupplyTypeArray(split);
            }
        }
        return pageList;
    }

    /**
     * 新增公司
     * @param organ 公司信息
     * @return Result<Object>
     */
    @Override
    public Result<Object> addOrgan(Organ organ) {
        String organType = WebUtils.getUser().getOrganType();
        // 如果登录用户不是平台用户，则新增子公司有限制
        if (!OrganTypeEnum.PLATFORM.getCode().equals(organType)) {
            Organ loginOrgan = getById(WebUtils.getUser().getOrganId());
            Integer childNum = loginOrgan.getChildNum();
            // 如果子公司限制数不为空，则做新增子公司限制
            if (!BeanUtil.isEmpty(childNum)) {
                int count = count(Wrappers.lambdaQuery(Organ.class)
                        .eq(Organ::getOrganId, WebUtils.getUser().getOrganId()));
                if (count >= childNum) {
                    return Result.fail("子公司数超过限制，新增失败！");
                }
            }
        }
        insertOrgan(organ);
        return Result.success();
    }

    /**
     * 新增公司
     * @param organ 公司信息
     */
    private void insertOrgan(Organ organ) {
        String[] foodSupplyTypeArray = organ.getFoodSupplyTypeArray();
        if(BeanUtil.isNotEmpty(foodSupplyTypeArray)) {
            String foodSupplyTypes = String.join(StrUtil.COMMA, foodSupplyTypeArray);
            organ.setFoodSupplyTypes(foodSupplyTypes);
        }
        save(organ);
    }

    /**
     * 修改公司
     * @param organ 公司信息
     * @return Result<Object>
     */
    @Override
    public Result<Object> updateOrgan(Organ organ) {
        String[] foodSupplyTypeArray = organ.getFoodSupplyTypeArray();
        if (ArrayUtil.isNotEmpty(foodSupplyTypeArray)) {
            String foodSupplyTypes = String.join(StrUtil.COMMA, foodSupplyTypeArray);
            organ.setFoodSupplyTypes(foodSupplyTypes);
        }
        updateById(organ);
        return Result.success();
    }

    /**
     * 删除公司
     * @param organIds 公司Ids
     * @return Result<Object>
     */
    @Override
    public Result<Object> deleteOrgan(String organIds) {
        String[] organIdArray = organIds.split(StrUtil.COMMA);
        List<Long> organIdList = new ArrayList<>();
        for (String organId : organIdArray) {
            // 公司下有用户，不能删除
            int userCount = userService.count(Wrappers.lambdaQuery(SysUser.class)
                    .eq(SysUser::getOrganId, organId));
            if (userCount != 0) {
                return Result.fail("该公司下有用户，不能删除！");
            }
            // 公司下有角色，不能删除
            int roleCount = roleService.count(Wrappers.lambdaQuery(Role.class)
                    .eq(Role::getOrganId, organId));
            if (roleCount != 0) {
                return Result.fail("该公司下有角色，不能删除！");
            }
            organIdList.add(Long.parseLong(organId));
        }
        removeByIds(organIdList);
        return Result.success();
    }

    /**
     * 修改公司状态
     * @param organ 公司状态信息
     * @return Result<Object>
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> changeOrganStatus(Organ organ) {
        // 修改公司用户状态
        userService.update(Wrappers.lambdaUpdate(SysUser.class)
        .set(SysUser::getStatus, organ.getStatus())
        .eq(SysUser::getOrganId, organ.getId()));
        // 修改公司角色状态
        roleService.update(Wrappers.lambdaUpdate(Role.class)
        .set(Role::getStatus, organ.getStatus())
        .eq(Role::getOrganId, organ.getId()));
        // 修改公司状态
        updateById(organ);
        return Result.success();
    }

    /**
     * 条件分页查询公司树形列表
     * @param page 分页条件
     * @param name 公司名称
     * @param status 公司状态
     * @param beginTime 开始时间
     * @param endTime 结束时间
     * @return IPage<Organ>
     */
    @Override
    public IPage<Organ> treeList(Page<Organ> page, String name, String status, String beginTime, String endTime) {
        Long organId = WebUtils.getUser().getOrganId();
        Page<Organ> pageList = page(page, Wrappers.lambdaQuery(Organ.class)
                .eq(Organ::getOrganId, organId)
                .eq(StrUtil.isNotBlank(name), Organ::getName, name)
                .eq(StrUtil.isNotBlank(status), Organ::getStatus, status)
                .ge(StrUtil.isNotBlank(beginTime), Organ::getCreateTime, beginTime)
                .le(StrUtil.isNotBlank(endTime), Organ::getCreateTime, endTime));
        List<Organ> records = pageList.getRecords();
        getChildOrganList(records);
        return pageList;
    }

    /**
     * 获取公司子树列表
     * @param organList 父公司列表
     */
    private void getChildOrganList(List<Organ> organList) {
        if (!organList.isEmpty()) {
            for (Organ organ : organList) {
                List<Organ> list = list(Wrappers.lambdaQuery(Organ.class)
                        .eq(Organ::getOrganId, organ.getId()));
                if (!list.isEmpty()) {
                    organ.setChildren(list);
                    getChildOrganList(list);
                }
            }
        }
    }

    /**
     * 查询树形结构的子结构列表
     * @param treeSelect treeSelect
     */
    private void selectChildren(TreeSelect treeSelect) {
        List<TreeSelect> children = baseMapper.selectChildren(treeSelect.getId());
        if (!children.isEmpty()) {
            treeSelect.setChildren(children);
            children.forEach(this::selectChildren);
        }
    }
}
